package mouse

import (
	"log"
	"time"

	"github.com/AllenDang/w32"
)

const (
	LBUTTON    = 0
	RBUTTON    = 1
	MBUTTON    = 2
	DLBUTTON   = 3
	DRBUTTON   = 4
	SCROLLUP   = 5
	SCROLLDOWN = 6
	MOVE       = 7
)

type MouseAction struct {
	X, Y       int32
	ActionType int
}

func (m *MouseAction) Perform() {
	switch m.ActionType {
	case LBUTTON, RBUTTON, MBUTTON:
		click(m)
	case DLBUTTON, DRBUTTON:
		doubleClick(m)
	case MOVE:
		move(m)
	default:
		log.Println("not a valid mouse action")
	}
}

type RPCMouse int

func (rpcMouse *RPCMouse) RPCPerform(m *MouseAction, result *int) error {
	m.Perform()
	return nil
}

func (m *MouseAction) SetPos(x, y int32) {
	// todo
	m.X = (x * 65535) / 100
	m.Y = (y * 65535) / 100
}

func move(mouseAction *MouseAction) {
	var mouseInputs [1]w32.INPUT
	mouseInputs[0].Mi.Dx, mouseInputs[0].Mi.Dy = mouseAction.X, mouseAction.Y
	mouseInputs[0].Type = w32.INPUT_MOUSE
	mouseInputs[0].Mi.DwFlags = w32.MOUSEEVENTF_ABSOLUTE | w32.MOUSEEVENTF_MOVE
	w32.SendInput(mouseInputs[:])
}

func click(mouseAction *MouseAction) {
	var mouseInputs [2]w32.INPUT
	mouseInputs[0].Type = w32.INPUT_MOUSE
	mouseInputs[1].Type = w32.INPUT_MOUSE
	switch mouseAction.ActionType {
	case LBUTTON:
		mouseInputs[0].Mi.DwFlags = w32.MOUSEEVENTF_LEFTDOWN
		mouseInputs[1].Mi.DwFlags = w32.MOUSEEVENTF_LEFTUP
		log.Println(w32.SendInput(mouseInputs[:]))
	case RBUTTON:
		mouseInputs[0].Mi.DwFlags = w32.MOUSEEVENTF_RIGHTDOWN
		mouseInputs[1].Mi.DwFlags = w32.MOUSEEVENTF_RIGHTUP
		w32.SendInput(mouseInputs[:])
	case MBUTTON:
		mouseInputs[0].Mi.DwFlags = w32.MOUSEEVENTF_MIDDLEDOWN
		mouseInputs[1].Mi.DwFlags = w32.MOUSEEVENTF_MIDDLEUP
		w32.SendInput(mouseInputs[:])
	}
}

func doubleClick(mouseAction *MouseAction) {
	switch mouseAction.ActionType {
	case DLBUTTON:
		mouseAction.ActionType = LBUTTON
		click(mouseAction)
		time.Sleep(10 * time.Millisecond)
		click(mouseAction)
		mouseAction.ActionType = DLBUTTON
	case DRBUTTON:
		mouseAction.ActionType = RBUTTON
		click(mouseAction)
		time.Sleep(10 * time.Millisecond)
		click(mouseAction)
		mouseAction.ActionType = DRBUTTON
	}
}
